//
// Created by lm379 on 25-3-17.
//
#include <iostream>
#include <cmath>
#include <cstring>
#define maxSize 100
#define MIN 1e-9
using namespace std;

int getPriority(const char ch) {
    if (ch == '+' || ch == '-')
        return 0;
    if (ch == '(')
        return -1;
    return 1;
}

bool calSub(const char op, const double num1, const double num2, double &result) {
    switch (op) {
        case '+':
            result = num1 + num2;
            break;
        case '-':
            result = num1 - num2;
            break;
        case '*':
            result = num1 * num2;
            break;
        case '/':
            if (fabs(num2) < MIN)
                return false;
            result = num1 / num2;
            break;
        default:
            return false;
    }
    return true;
}

bool calStackTopTwo(double number[], int &top1, char op[], int &top2) {
    double num2 = number[top1--];
    double num1 = number[top1--];
    double result;
    bool flag = calSub(op[top2--],num1,num2,result);
    if (flag == false) {
        cout << "ERROR" << endl;
        return false;
    }
    number[++top1] = result;
    return true;
}

double solveInfix(char infix[]) {
    double number[maxSize];
    int top1 = -1;
    char op[maxSize];
    int top2 = -1;
    int i = 0;
    while (infix[i] != '\0') {
        if (infix[i] >= '0' && infix[i] <= '9') {
            number[++top1] = infix[i++] - '0';
        } else if (infix[i] == '(') {
            op[++top2] = infix[i++];
        } else if (infix[i] == '+' || infix[i] == '-' || infix[i] == '*' || infix[i] == '/' ) {
            if (top2 == -1 || getPriority(infix[i]) > getPriority(op[top2])) {
                op[++top2] = infix[i++];
            } else {
                bool res = calStackTopTwo(number,top1,op,top2);
                if (!res)
                    return 0;
            }
        } else if (infix[i] == ')') {
            while (op[top2] != '(') {
                bool res = calStackTopTwo(number,top1,op,top2);
                if (!res)
                    return 0;
            }
            top2--;
            i++;
        } else {
            i++;
        }
    }
    while (top2 != -1) {
        bool res = calStackTopTwo(number,top1,op,top2);
        if (!res)
            return 0;
    }
    return number[top1];
}

double solvePostfix(char postfix[]) {
    double number[maxSize];
    int top = -1;
    int i = 0;
    while (postfix[i] != '\0') {
        if (postfix[i] >= '0' && postfix[i] <= '9') {
            number[++top] = postfix[i] - '0';
        } else if (postfix[i] == '+' || postfix[i] == '-' || postfix[i] == '*' || postfix[i] == '/') {
            double num2 = number[top--];
            double num1 = number[top--];
            double result;
            bool flag = calSub(postfix[i],num1,num2,result);
            if (!flag) {
                cout << "ERROR" << endl;
                return 0;
            }
            number[++top] = result;
        }
        i++;
    }
    return number[top];
}

double sovlePrefix(char prefix[]) {
    double number[maxSize];
    int top = -1;
    for (int i = strlen(prefix) - 1; i >= 0;i--) {
        if (prefix[i] >= '0' && prefix[i] <= '9') {
            number[++top] = prefix[i] - '0';
        } else if (prefix[i] == '+' || prefix[i] == '-' || prefix[i] == '*' || prefix[i] == '/') {
            double num1 = number[top--];
            double num2 = number[top--];
            double result;
            bool flag = calSub(prefix[i],num1,num2,result);
            if (!flag) {
                cout << "ERROR" << endl;
                return 0;
            }
            number[++top] = result;
        }
    }
    return number[top];
}

int main() {
    char strInfix[] = "(3+4)*5/8";
    char strPostfix[] = "1 5 2 5 8 + 4 / - * +";
    char strPrefix[] = "/ * + 3 4 5 8";
    cout << solveInfix(strInfix) << endl;
    cout << solvePostfix(strPostfix) << endl;
    cout << sovlePrefix(strPrefix) << endl;
    return 0;
}